package api

import (
	"fmt"
	"hello/dao"
	"hello/tools"
	"log"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"

	mysql "hello/mysql"

	myjwt "hello/jwt"
)

func LoginDB(c *gin.Context) {
	name, number, gender, class, college, major, phone, qq := c.Request.URL.Query().Get("name"), c.Request.URL.Query().Get("number"), c.Request.URL.Query().Get("gender"), c.Request.URL.Query().Get("class"), c.Request.URL.Query().Get("college"), c.Request.URL.Query().Get("major"), c.Request.URL.Query().Get("phone"), c.Request.URL.Query().Get("qq")
	status, msg, user, token := mysql.InsertUser(name, number, gender, class, college, major, phone, qq)
	if status == 300 {
		c.JSON(200, gin.H{
			"code": 300,
			"msg":  "查询时出错！",
			"err":  msg,
		})
	} else if status == 301 {
		c.JSON(200, gin.H{
			"code": 301,
			"msg":  "存储信息条数时出错!",
			"err":  msg,
		})
	} else if status == 303 {
		c.JSON(200, gin.H{
			"code": 303,
			"msg":  "该用户已经注册过！",
			"err":  "数据库中已有该用户信息",
		})
	} else if status == 304 {
		c.JSON(http.StatusOK, gin.H{
			"code": 304,
			"msg":  "用户信息不完整，请确认用户信息是否完整！",
		})
	} else if status == 400 {
		c.JSON(200, gin.H{
			"code": 400,
			"msg":  msg,
		})
	} else if status == 401 {
		c.JSON(200, gin.H{
			"code": 401,
			"msg":  msg,
		})
	} else if status == 500 {
		timeNow := time.Now().Format("2006-01-02 15:04:05")
		str := "<h2>注册成功</h2>"
		str += "<p><b>时间：</b>" + timeNow + "</p>"
		str += "<p><b>注册用户：</b>" + user.Name + "</p>"
		str += "<p><b>性别：</b>" + user.Gender + "</p>"
		str += "<p><b>学号：</b>" + user.Number + "</p>"
		str += "<p><b>组别：</b>" + user.Class + "</p>"
		str += "<p><b>学院：</b>" + user.College + "</p>"
		str += "<p><b>专业：</b>" + user.Major + "</p>"
		str += "<p><b>电话：</b>" + user.Phone + "</p>"
		str += "<p><b>QQ：</b>" + user.QQ + "</p>"
		objectArr := []string{
			"2558980534@qq.com",
			user.QQ + "@qq.com",
		}
		code, err := tools.HandleSendEmail(objectArr, "新用户注册信息", str)
		if code == 400 {
			c.JSON(200, gin.H{
				"code":  402,
				"msg":   "用户信息已成功上传，邮件发送失败",
				"err":   err,
				"user":  user,
				"token": token,
			})
		} else if code == 500 {
			c.JSON(200, gin.H{
				"code":  500,
				"msg":   "用户信息已上传，邮件发送已成功发送",
				"user":  user,
				"token": token,
			})
		}
		qqMessage := ""
		qqMessage += "报名时间：" + timeNow
		qqMessage += "姓名：" + user.Name
		qqMessage += "性别：" + user.Gender
		qqMessage += "学号：" + user.Number
		qqMessage += "组别：" + user.Class
		qqMessage += "学院：" + user.College
		qqMessage += "专业：" + user.Major
		qqMessage += "电话：" + user.Phone
		qqMessage += "QQ:" + user.QQ
		//qqMessage += "姓名为："+ user.Name +"的用户报名成功，学院是" + user.College + ",专业为" + user.Major
		group := "54535282"
		fmt.Println(qqMessage)
		_,ss := tools.SendQQMessage(qqMessage, group)
		fmt.Println(ss)
	}
}

func GetUserByName(c *gin.Context){
	name := c.Query("name")
	code,err,users := mysql.GetUserByName(name)
	if code == 401 || code == 402{
		c.JSON(http.StatusBadRequest,gin.H{
			"code": code,
			"status": "failed",
			"error": err,
		})
	}else if code == 500{
		c.JSON(http.StatusOK,gin.H{
			"code": code,
			"status": "ok",
			"data": users,
			"l": len(users),
		})
	}
}

func GetAllTeamers(c *gin.Context) {
	status, err, arr := mysql.GetAllTeamers()
	if status == 401 {
		c.JSON(200, gin.H{
			"code":  401,
			"error": err,
		})
	} else if status == 402 {
		c.JSON(200, gin.H{
			"code":  402,
			"error": err,
		})
	} else if status == 500 {
		c.JSON(200, gin.H{
			"code": 500,
			"msg":  "success",
			"data": arr,
		})
	}
}

func GetTeamClass(c *gin.Context) {
	var id = c.Request.URL.Query().Get("id")
	status, err, arr := mysql.GetTeamClass(id)
	if status == 401 {
		c.JSON(200, gin.H{
			"code":  401,
			"error": err,
		})
	} else if status == 402 {
		c.JSON(200, gin.H{
			"code":  402,
			"error": err,
		})
	} else if status == 500 {
		c.JSON(200, gin.H{
			"code": 500,
			"msg":  "success",
			"data": arr,
		})
	}
}

func AuthHandler(c *gin.Context) {
	// 用户发送用户名和密码过来
	var user dao.UserInfo
	err := c.ShouldBind(&user)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 2001,
			"msg":  "无效的参数",
		})
		return
	}
	// 校验用户名和密码是否正确

	// 生成Token
	tokenString, _ := myjwt.GenToken(user.UserID, user.Username, user.Number)
	c.JSON(http.StatusOK, gin.H{
		"code": 2000,
		"msg":  "success",
		"data": gin.H{"token": tokenString},
	})
	return
}

func GetUser(c *gin.Context) {
	id := c.Request.URL.Query().Get("id")
	status, msg, user := mysql.GetUser(id)
	if status == 401 {
		c.JSON(200, gin.H{
			"code": 401,
			"err":  msg,
		})
	} else if status == 402 {
		c.JSON(200, gin.H{
			"code": 402,
			"err":  msg,
		})
	} else if status == 500 {
		c.JSON(200, gin.H{
			"code": 500,
			"msg":  "success",
			"data": user,
		})
	}
}



func GetImgArr(c *gin.Context) {
	code, msg, list := mysql.GetImgList()
	if code == 401 {
		c.JSON(http.StatusOK, gin.H{
			"code": 401,
			"err":  msg,
		})
	} else if code == 402 {
		c.JSON(http.StatusOK, gin.H{
			"code": 402,
			"err":  msg,
		})
	} else if code == 500 {
		c.JSON(http.StatusOK, gin.H{
			"code": 500,
			"msg":  "ok",
			"data": list,
		})
	}
}

func GetAllUser(c *gin.Context) {
	code, msg, userArray, l := mysql.GetAllUser()
	if code == 401 {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":   401,
			"msg":    msg,
			"status": "err",
		})
	} else if code == 500 {
		c.JSON(http.StatusOK, gin.H{
			"code":   500,
			"msg":    "success",
			"status": "ok",
			"l":    l,
			"data":   userArray,
		})
	}

}

func ModifyUser(c *gin.Context) {
	var user dao.User
	fmt.Println("token = " + c.Request.Header.Get("Authorization"))
	code, msg, userID, userName, _ := tools.JWTAuthMiddleware(c.Request.Header.Get("Authorization"))
	fmt.Println("userID = " + userID)
	if code == 404 {
		c.JSON(http.StatusNotFound, gin.H{
			"code":   404,
			"msg":    msg,
			"status": "err",
		})
	} else if code == 401 {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":   401,
			"msg":    "token格式不正确或token无效",
			"status": "err",
		})
	} else if code == 500 {
		fmt.Println("token验证成功")
		if err := c.ShouldBind(&user); err == nil {
			fmt.Println(user)
			if userID == user.ID || userName == "admin" { // 权限认证成功
				status, msg, userData := mysql.ModifyUser(user)
				if status == 401 || status == 402 {
					c.JSON(http.StatusBadRequest, gin.H{
						"code": 401,
						"jwt":  "权限认证成功",
						"op":   userName,
						"msg":  "err",
						"err":  msg,
					})
				} else if status == 500 {
					c.JSON(http.StatusAccepted, gin.H{
						"jwt":  "权限认证成功",
						"op":   userName,
						"code": status,
						"msg":  msg,
						"user": userData,
					})
				}
			} else { // 权限认证失败
				c.JSON(http.StatusBadRequest, gin.H{
					"status": "failed",
					"code":   402,
					"msg":    "您没有权限修改该用户的信息",
				})
			}

		} else {
			c.JSON(http.StatusBadRequest, gin.H{
				"msg":  "未知错误，请联系管理员(QQ:54535282)处理",
				"code": 404,
			})
		}
	}
}

func ParseToken(c *gin.Context){
	token := c.Query("token")
	status,_,_,userName,_ :=tools.JWTAuthMiddleware(token)
	if status == 404{
		c.JSON(http.StatusBadRequest,gin.H{
			"code":   404,
			"msg":    "未识别到token",
			"status": "failed",
		})
	}else if status == 401 {
		c.JSON(401, gin.H{
			"code":   401,
			"msg":    "token格式不正确或token已失效",
			"status": "failed",
		})
	} else if status == 500{
		c.JSON(http.StatusOK,gin.H{
			"code": 500,
			"status": "ok",
			"name": userName,
		})
	}
}

func DeleteUser(c *gin.Context) { // 删除用户
	var userFromHeader dao.User
	token := c.Request.Header.Get("Authorization")
	status, _, userID, userName, _ := tools.JWTAuthMiddleware(token)
	if status == 404 {
		c.JSON(http.StatusNotFound, gin.H{
			"code":   404,
			"msg":    "未识别到token",
			"status": "failed",
		})
	} else if status == 401 {
		c.JSON(401, gin.H{
			"code":   401,
			"msg":    "token格式不正确或token已失效",
			"status": "failed",
		})
	} else if status == 500 {
		fmt.Println("token验证成功")
		if err := c.ShouldBind(&userFromHeader); err == nil {
			if userFromHeader.ID == userID || userName == "admin" { // 如果操作人是本人，或者是管理员
				code, msg, user := mysql.DeleteUser(userFromHeader)
				if code == 404 {
					c.JSON(http.StatusNotFound, gin.H{
						"code":   404,
						"msg":    "该用户不存在",
						"status": "failed",
					})
				} else if code == 401 || code == 402 {
					c.JSON(http.StatusAccepted, gin.H{
						"code":   401,
						"err":    msg,
						"status": "failed",
					})
				} else if code == 500 {
					c.JSON(http.StatusOK, gin.H{
						"code":   500,
						"status": "success",
						"msg":    "删除成功",
						"data":   user,
					})
				}
			} else {
				c.JSON(http.StatusForbidden, gin.H{
					"code":   http.StatusForbidden,
					"status": "failed",
					"msg":    "您没有权限这么做",
				})
			}

		} else {
			c.JSON(http.StatusBadRequest, gin.H{
				"err":    err.Error(),
				"status": "failed",
			})
		}
	}
}

func GetAllComments(c *gin.Context) { // 获取所有的评论
	code, err, commentArray := mysql.GetAllComments()
	if code == 401 || code == 402 {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":   code,
			"error":  err,
			"status": "failed",
		})
	} else if code == 500 {
		c.JSON(http.StatusOK, gin.H{
			"code":     500,
			"status":   "ok",
			"comments": commentArray,
			"l": len(commentArray),
		})
	}
}

func GetCommentByName(c *gin.Context){
	username := c.Query("name")
	code,err,arr := mysql.GetCommentByName(username)
	if code == 401 || code == 402{

		c.JSON(http.StatusBadRequest,gin.H{
			"code": code,
			"status": "failed",
			"error": err,
		})
	}else if code == 500{
		c.JSON(http.StatusOK,gin.H{
			"code": 500,
			"status": "ok",
			"comments": arr,
			"l": len(arr),
		})
	}
}

func InsertComment(c *gin.Context) { // 发表评论
	var commentData dao.Comment
	if err := c.ShouldBind(&commentData); err != nil {
		commentData.Time = time.Now()
		if commentData.Username == "" || commentData.Number == "" || commentData.Content == "" {
			c.JSON(http.StatusNotFound, gin.H{
				"code":   404,
				"msg":    "请检查字段是否完整",
				"status": "failed",
			})
			return
		}
		code, err, id, comment := mysql.InsertComment(commentData)
		if code == 401 || code == 402 {
			c.JSON(http.StatusBadRequest, gin.H{
				"code":   code,
				"err":    err,
				"status": "failed",
			})
		} else if code == 500 {
			c.JSON(http.StatusOK, gin.H{
				"code":    500,
				"status":  "ok",
				"id":      id,
				"comment": comment,
			})
		}
	} else {
		c.JSON(http.StatusNotFound, gin.H{
			"code": 404,
			"msg":  "传入数据格式错误，请检查！",
		})
	}
}

func DeleteComment(c *gin.Context) {
	var commentData dao.Comment
	token := c.Request.Header.Get("Authorization")
	status, message, _, userName, _ := tools.JWTAuthMiddleware(token)
	if status == 404 {
		c.JSON(http.StatusNotFound, gin.H{
			"code":   404,
			"status": "failed",
			"error":  message,
		})
	} else if status == 401 {
		c.JSON(200, gin.H{
			"code":   status,
			"status": "failed",
			"error":  message,
		})
	} else if status == 500 {
		if userName == "admin" {
			if err := c.ShouldBind(&commentData); err == nil {
				code, msg, comment := mysql.DeleteComment(commentData)
				if code == 401 || code == 402 {
					c.JSON(200, gin.H{
						"code":   code,
						"status": "failed",
						"error":  msg,
					})
				} else if code == 500 {
					c.JSON(200, gin.H{
						"code":      500,
						"status":    "success",
						"CommentID": commentData.ID,
						"comment":   comment,
					})
				} else {
					c.JSON(200, gin.H{
						"msg": "未知错误，请联系管理员(54535282)",
					})
				}
			} else {
				c.JSON(http.StatusNotFound, gin.H{
					"code":   404,
					"status": "failed",
					"msg":    "传入格式错误",
				})
			}
		} else {
			c.JSON(http.StatusBadRequest, gin.H{
				"code":   403,
				"status": "failed",
				"error":  "您没有权限这么做",
			})
		}
	}

}

func UpdateComment(c *gin.Context) {
	var commentData dao.Comment
	token := c.Request.Header.Get("Authorization")
	status, msg, _, userName, _ := tools.JWTAuthMiddleware(token)

	if status == 404 {
		c.JSON(http.StatusNotFound, gin.H{
			"code":   404,
			"status": "failed",
			"error":  msg,
		})
	} else if status == 401 {
		c.JSON(200, gin.H{
			"code":   status,
			"status": "failed",
			"error":  msg,
		})
	} else if status == 500 {
		if err := c.ShouldBind(&commentData); err == nil {
			fmt.Println("userName = " + userName)
			if userName == "admin" {
				code, msg, comment := mysql.UpdateComment(commentData)
				if code == 401 || code == 402 {
					c.JSON(200, gin.H{
						"code":   code,
						"status": "failed",
						"error":  msg,
					})
				} else if code == 500 {
					c.JSON(200, gin.H{
						"code":      500,
						"status":    "success",
						"CommentID": commentData.ID,
						"comment":   comment,
					})
				} else {
					c.JSON(200, gin.H{
						"msg": "未知错误",
					})
				}
			} else {
				c.JSON(http.StatusBadRequest, gin.H{
					"code":   403,
					"status": "failed",
					"error":  "您没有权限这么做",
				})
			}
		} else {
			c.JSON(200, gin.H{
				"code":   404,
				"status": "failed",
				"msg":    err.Error(),
			})
		}
	}
}

func GetSingleComment(c *gin.Context) {
	id := c.Query("id")
	code, msg, comment := mysql.GetSingleComment(id)
	if code == 401 {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":   401,
			"status": "failed",
			"error":  msg,
		})
	} else if code == 500 {
		c.JSON(http.StatusOK, gin.H{
			"code":      500,
			"status":    "ok",
			"comment":   comment,
			"commentID": comment.ID,
		})
	}
}


func GetAllProcesses(c *gin.Context){
	code,err,arr := mysql.GetAllProcesses()
	if code == 401 || code == 402{
		c.JSON(http.StatusBadRequest,gin.H{
			"code": code,
			"status": "failed",
			"err": err,
		})
	}else if code == 500{
		c.JSON(http.StatusOK,gin.H{
			"code": 500,
			"status": "ok",
			"data": arr,
			"length": len(arr),
		})
	}
}

func GetSingleProcess(c *gin.Context){
	id := c.Param("id")
	code,err,process := mysql.GetSingleProcess(id)
	if code == 401{
		c.JSON(http.StatusBadRequest,gin.H{
			"code": code,
			"error": err,
			"status": "failed",
		})
	}else if code == 500{
		c.JSON(http.StatusOK,gin.H{
			"code": 500,
			"data": process,
			"status": "ok",
		})
	}
}

func UpdateProcess(c *gin.Context){
	process := dao.Process{
		Num:     c.PostForm("num"),
		Title:   c.PostForm("title"),
		Content: c.PostForm("content"),
	}
	code,err,data := mysql.UpdateProcess(process)
	if code == 401 || code == 402{
		c.JSON(http.StatusBadRequest,gin.H{
			"code": code,
			"error": err,
			"status": "failed",
		})
	}else if code == 500{
		c.JSON(http.StatusOK,gin.H{
			"code": code,
			"status": "ok",
			"data": data,
		})
	}
}

func GetAllShowData(c *gin.Context){
	code,err,showDataArray := mysql.GetAllShowData()
	if code == 401 || code == 402{
		c.JSON(http.StatusBadRequest,gin.H{
			"code": code,
			"err": err,
			"status": "failed",
		})
	} else if code == 500{
		c.JSON(http.StatusOK,gin.H{
			"code": 500,
			"status": "ok",
			"data": showDataArray,
		})
	}
}

func GetClassShowData(c *gin.Context){
	types := c.Param("type")
	code,err,showDataArray := mysql.GetClassShowData(types)
	if code == 401 || code == 402{
		c.JSON(http.StatusBadRequest,gin.H{
			"code": code,
			"status": "failed",
			"error": err,
		})
	}else if code == 500{
		c.JSON(http.StatusOK,gin.H{
			"code": code,
			"status": "ok",
			"data": showDataArray,
		})
	}
}
func GetShowDataClassSum(c *gin.Context){
	code,err,data := mysql.GetShowDataClassSum()
	if code == 401{
		c.JSON(http.StatusBadRequest,gin.H{
			"code": 401,
			"status": "failed",
			"error": err,
		})
	} else if code == 500{
		c.JSON(http.StatusOK,gin.H{
			"code": 500,
			"status": "ok",
			"data": data,
		})
	}
}
func SendEmail(c *gin.Context){
	targetUser := c.Param("target")
	title := c.Param("title")
	content := c.Param("content")
	mailBody := dao.MailBody{
		TargetUser: targetUser,
		Title:      title,
		Content:    content,
	}
	var targetUsers []string
	targetUsers = append(targetUsers,targetUser)
	err := tools.SendMail(targetUsers,title,content)
	if err != nil {
		log.Println(err)
		fmt.Println("send failed")
		c.JSON(http.StatusBadRequest,gin.H{
			"code": 400,
			"status": "failed",
			"error": err,
		})
	} else {
		fmt.Println("success")

		c.JSON(http.StatusOK,gin.H{
			"code": 500,
			"status": "ok",
			"mail":mailBody,
		})
	}
}


func AddYuqAdmin(c *gin.Context){
	qq := c.Param("qq")
	code,msg,_ := mysql.CheckYuQAdmin(qq)
	if code == 500{
		code,err,n := mysql.AddYuqAdmin(qq)
		if code == 401 || code == 402{
			c.JSON(http.StatusOK,gin.H{
				"code": code,
				"status": "failed",
				"error": err,
			})
		}else if code == 500{
			c.JSON(http.StatusOK,gin.H{
				"code": 500,
				"id": n,
				"status": "ok",
			})
		}
	}else{
		c.JSON(http.StatusOK,gin.H{
			"code": 404,
			"status": "failed",
			"msg": msg,
		})
	}
}

func GetAllYuqAdmin(c *gin.Context){
	code,err,arr := mysql.GetAllYuqAdmin()
	if code == 401 || code == 402{
		c.JSON(http.StatusBadRequest,gin.H{
			"code": code,
			"status": "failed",
			"error": err,
		})
	}else if code == 500{
		c.JSON(http.StatusOK,gin.H{
			"code": code,
			"status": "ok",
			"data": arr,
		})
	}
}

func GetAllAward(c *gin.Context){
	code,err,arr := mysql.GetAllAward()
	if code == 401 || code == 402{
		c.JSON(http.StatusBadRequest,gin.H{
			"code": code,
			"status": "failed",
			"error": err,
		})
	}else if code == 500{
		c.JSON(http.StatusOK,gin.H{
			"code": 500,
			"status": "ok",
			"data": arr,
			"l": len(arr),
		})
	}
}

func GetUserSex(c *gin.Context){
	code,err,gender := mysql.GetUserSex()
	if code == 401{
		c.JSON(http.StatusBadRequest,gin.H{
			"code": 401,
			"status": "failed",
			"error": err,
		})
	}else if code == 500{
		c.JSON(http.StatusOK,gin.H{
			"code": 500,
			"status": "ok",
			"data": gender,
		})
	}
}

func GetGenderForClasses(c *gin.Context){
	code,err,data := mysql.GetGenderForClasses()
	if code == 401{
		c.JSON(http.StatusBadRequest,gin.H{
			"code": code,
			"status": "failed",
			"error": err,
		})
	}else if code == 500{
		c.JSON(http.StatusOK,gin.H{
			"code": 500,
			"status": "ok",
			"data": data,
			"sum": data.ZhiNengMan+data.KaiFaMan+data.KaiFaWoman+data.ZhiNengWoman,
		})
	}
}

func CheckMusicName(c *gin.Context){
	musicName := c.Query("name")
	code,err,msg := mysql.CheckMusicName(musicName)
	if code == 401{
		c.JSON(200,gin.H{
			"code": 401,
			"status": "failed",
			"error":  err,
		})
	} else if code == 404{
		c.JSON(200,gin.H{
			"code": 404,
			"status": "failed",
			"msg": msg,
		})
	} else if code == 500{
		c.JSON(http.StatusOK,gin.H{
			"code": 500,
			"status": "ok",
			"msg": msg,
		})
	}
}